home *** CD-ROM | disk | FTP | other *** search
- /*
- * INIT.C
- *
- * LibMain entry point and initialization code for the MicroScroll
- * custom control DLL that is likely to be used once or very
- * infrequently.
- *
- * Version 1.1, October 1991, Kraig Brockschmidt
- */
-
-
- #include <windows.h>
- #include "muscrdll.h"
-
-
- HANDLE hgInst; //Need this for dialog editor style box.
-
-
- /*
- * LibMain
- *
- * Purpose:
- * DLL-specific entry point called from LibEntry. Initializes
- * the DLL's heap and registers the MicroScroll custom control
- * class.
- *
- * Parameters:
- * hInstance HANDLE instance of the DLL.
- * wDataSeg WORD segment selector of the DLL's data segment.
- * wHeapSize WORD byte count of the heap.
- * lpCmdLine LPSTR to command line used to start the module.
- *
- * Return Value:
- * HANDLE Instance handle of the DLL.
- *
- */
-
- HANDLE FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg,
- WORD cbHeapSize, LPSTR lpCmdLine)
- {
- //Go register the control
- if (FRegisterControl(hInstance))
- {
- hgInst=hInstance;
-
- if (0!=cbHeapSize)
- UnlockData(0);
-
- return hInstance;
- }
-
- hgInst=NULL;
- return (HANDLE)NULL;
- }
-
-
-
-
- /*
- * FRegisterControl
- *
- * Purpose:
- * Registers the MicroScroll control class, including CS_GLOBALCLASS
- * to make the control available to all applications in the system.
- *
- * Parameters:
- * hInstance HANDLE Instance of the application or DLL that will
- * own this class.
- *
- * Return Value:
- * BOOL TRUE if the class is registered, FALSE otherwise.
- * TRUE is also returned if the class was already
- * registered.
- */
-
- BOOL PASCAL FRegisterControl(HANDLE hInstance)
- {
- static BOOL fRegistered=FALSE;
- WNDCLASS wc;
- char szClass[40];
-
- if (!fRegistered)
- {
- //Load the class name
- if (0==LoadString(hInstance, IDS_CLASSNAME, szClass, 40))
- return FALSE;
-
- wc.lpfnWndProc = MicroScrollWndProc;
- wc.cbClsExtra = CBCLASSEXTRA;
- wc.cbWndExtra = CBWINDOWEXTRA;
- wc.hInstance = hInstance;
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = COLOR_BTNFACE+1;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = szClass;
- wc.style = CS_DBLCLKS | CS_GLOBALCLASS |
- CS_VREDRAW | CS_HREDRAW;
-
- fRegistered=RegisterClass(&wc);
- }
-
- return fRegistered;
- }
-
-
-
- /*
- * LMicroScrollCreate
- *
- * Purpose:
- * Handles both WM_NCCREATE and WM_CREATE messages:
- * WM_NCCREATE: Allocate control MUSCROLL structure. Any sort
- * of initialization that should force the create
- * to fail should be included in this case.
- *
- * WM_CREATE: Fill the MUSCROLL structure; parse the text
- * for initial min, max, and position for the
- * MSS_TEXTHASRANGE style; clear all states;
- * set the expansion handle to NULL.
- *
- * Parameters:
- * hWnd HWND handle to the control window.
- * iMsg WORD message, either WM_NCCREATE or WM_CREATE.
- * pMS PMUSCROLL pointer to existing MUSCROLL structure.
- *
- * Return Value:
- * LONG 0L if memory could not be allocated on WM_NCCREATE.
- * 1L in all other cases.
- */
-
- LONG PASCAL LMicroScrollCreate(HWND hWnd, WORD iMsg, PMUSCROLL pMS,
- LPCREATESTRUCT lpCreate)
- {
- HANDLE hMem;
- BOOL fTextRange;
- WORD iMin, iMax, iPos;
-
-
- if (WM_NCCREATE==iMsg)
- {
- /*
- * Allocate extra FIXED memory for the control's MUSCROLL
- * structure and store that handle in the minimal window
- * extra bytes allocated for the control.
- *
- * Note that LPTR includes LMEM_ZEROINIT, so all fields are
- * initially zero.
- */
- hMem=LocalAlloc(LPTR, CBMUSCROLL);
-
- if (NULL==hMem)
- return 0L;
-
- SetWindowWord(hWnd, GWW_MUSCROLLHMEM, (HANDLE)hMem);
- }
-
- if (WM_CREATE==iMsg)
- {
- //Our associate is the parent by default.
- pMS->hWndAssociate=(HWND)GetWindowWord(hWnd, GWW_HWNDPARENT);
-
-
- //Copy styles
- pMS->dwStyle =lpCreate->style;
-
- /*
- * Enforce exclusive MSS_VERTICAL and MSS_HORIZONTAL,
- * defaulting to MSS_VERTICAL.
- */
- if ((MSS_VERTICAL & pMS->dwStyle) && (MSS_HORIZONTAL & pMS->dwStyle))
- pMS->dwStyle &= ~MSS_HORIZONTAL;
-
- //Either parse the text or use defaults for initial range.
- fTextRange=FALSE;
-
- if (MSS_TEXTHASRANGE & pMS->dwStyle)
- {
- fTextRange=FTextParse((LPSTR)lpCreate->lpszName,
- &iMin, &iMax, &iPos);
-
- /*
- * Verify that the position is in the given range. If
- * the position is outside the range, force it to the
- * middle.
- */
- if (fTextRange)
- {
- if (iPos < iMin || iPos > iMax)
- iPos=(iMin + iMax) >> 1;
- }
- }
-
-
-
- /*
- * Use defaults if we never had MSS_TEXTHASRANGE or
- * FTextParse failed.
- */
- pMS->iMin=(fTextRange ? iMin : IDEFAULTMIN);
- pMS->iMax=(fTextRange ? iMax : IDEFAULTMAX);
- pMS->iPos=(fTextRange ? iPos : IDEFAULTPOS);
-
- //Clear out all initial states.
- StateClear(pMS, MUSTATE_ALL);
-
- //Indicate that all colors are defaults.
- for (iMin=0; iMin < CCOLORS; iMin++)
- pMS->rgCr[iMin]=(COLORREF)-1L;
- }
-
- return 1L;
- }
-
-
-
- /*
- * FTextParse
- *
- * Purpose:
- * Parses window text for a valid range and initial position.
- * This function is used when creating the control or setting the
- * window text to set the initial range and position but is also
- * used to validate text entered in the Style dialog in the Dialog
- * Editor interface if the MSM_TEXTHASRANGE style is selected.
- *
- * The range and position must all be valid for any change to
- * occur in piMin, piMax, and piPos.
- *
- * Parameters:
- * psz LPSTR pointer to the window text to parse out
- * the range and the position.
- * piMin LPINT pointer to location to store minimum.
- * piMax LPINT pointer to location to store maximum.
- * piPos LPINT pointer to location to store position.
- *
- * Return Value:
- * BOOL TRUE if the function successfully initializes
- * the range and position. FALSE if any part of
- * the text is not a valid number between comma
- * delimeters.
- */
-
- BOOL PASCAL FTextParse(LPSTR psz, LPINT piMin, LPINT piMax, LPINT piPos)
- {
- int iMin;
- int iMax;
- int iCur;
-
- if (psz==NULL)
- return FALSE;
-
- /*
- * Parse off the bottom of the range. Note that we depend
- * on WTranslateUpToChar to modify psz to point to the character
- * after the delimeter which is why we pass &psz.
- */
- iMin=WTranslateUpToChar(&psz, ',');
-
- //Check for valid value AND that there's text remaining.
- if (-1==iMin || 0==*psz)
- return FALSE;
-
- //Parse off the top of the range.
- iMax=WTranslateUpToChar(&psz, ',');
-
- //Check for valid value AND that there's text remaining.
- if (-1==iMax || 0==*psz)
- return FALSE;
-
- //Parse off the position and validate it.
- iCur=WTranslateUpToChar(&psz, ',');
-
- if (-1==iCur)
- return FALSE;
-
- //Store the parsed values in the return locations.
- *piMin=iMin;
- *piMax=iMax;
- *piPos=iCur;
-
- return TRUE;
- }
-
-
-
-
-
- /*
- * WTranslateUpToChar
- *
- * Purpose:
- * Scans a string for digits, converting the series of digits to
- * an integer value as the digits are scanned. Scanning stops
- * at chDelimeter or the end of the string.
- *
- * If the scan sees a non-digit character, -1 is returned to indicate
- * error. If the scan sees a null-terminator before any text, we
- * return 0.
- *
- * Parameters:
- * ppsz LPSTR * pointer to pointer to the string to scan.
- * On return, the pointer will point to the character
- * after the delimeter OR the NULL terminator.
- *
- * We want a pointer to the pointer so we can modify
- * that pointer for the calling function since we are
- * using the return value for the parsed value
- *
- * chDelimiter char delimeter at which the scanning stops.
- *
- * Return Value:
- * WORD -1 if the string contains non-digits excluding
- * the comma. Otherwise the converted value is
- * returned and the pointer to the address after
- * the comma is stored at ppsz.
- */
-
- WORD PASCAL WTranslateUpToChar(LPSTR FAR *ppsz, char chDelimeter)
- {
- WORD wRet=0;
- char ch;
- LPSTR psz;
-
- psz=*ppsz;
-
- //Fail if there's no more string to parse.
- if (0==*psz)
- return -1;
-
- //Scan string, stopping at 0 or chDelimeter
- while (ch=*psz)
- {
- if (ch==chDelimeter)
- {
- psz++; //Skip delimeter
- break;
- }
-
- //Check for digits, returning -1 on a non-digit.
- ch-='0';
-
- if (ch < 0 || ch > 9)
- return -1;
-
- //Add up the value as we scan.
- wRet=(wRet*10) + (WORD)ch;
-
- /*
- * We increment psz here so if we hit a null-terminator
- * psz is always valid. If we incremented in the while
- * statement then psz might be past the null-terminator
- * and possibly invalid.
- */
- psz++;
- }
-
- /*
- * Store the new pointer and the value. Note that the *psz++
- * already incremented psz past the delimeter AND the zero.
- */
- *ppsz=psz;
- return wRet;
- }
-